package ema.tpjee.banking.dao;

import java.io.Serializable;
import java.util.List;
import java.util.Random;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import ema.tpjee.banking.model.Bank;
import ema.tpjee.banking.model.Customer;
import ema.tpjee.utils.Paging;
import ema.tpjee.utils.RandomString;


@Stateless
public class CustomerDaoImpl implements CustomerDao, Serializable {

	private static final long serialVersionUID = -5443611226894567253L;

	@PersistenceContext(unitName = "bankunit")
	private EntityManager entityManager = null;

	public CustomerDaoImpl() {
		super();
		System.out.println("creating CustomerDaoImpl");
	}

	public Customer find(Customer c) {
		return entityManager.find(Customer.class, c.getId());
	}

	public Customer add(Customer c) {
		if (find(c) == null) {
			entityManager.persist(c);
			return c;
		} else
			return null;
	}
	
	
	private Customer copyCustomer(Customer c) {
		Customer newc = create(c.getBank());
		if (c.getAddress() != null)
			newc.setAddress(c.getAddress());
		if (c.getName() != null)
			newc.setName(c.getName());
		if (c.getForName() != null)
			newc.setForName(c.getForName());
		// if (b.getZipCode() != 0)
		newc.setZipCode(c.getZipCode());
		// copier aussi les comptes
		return newc;
	}
	public Customer clone(Customer c) {
		Customer newc = copyCustomer(c);
		//entityManager.persist(newc);
		return newc;
	}
	
	public Customer clone(Bank b, Customer c) {
		Customer newc = copyCustomer(c);
		//Customer newc = new Customer(c.getName(),c.getForName(), c.getAddress(), c.getZipCode());
		//b.addCustomer(newc);
		//entityManager.persist(newc);
		//entityManager.merge(b);
		return newc;
	}

	public Customer create() {
		Customer newc = new Customer("noname");
		entityManager.persist(newc);
		return newc;
	}
	
	public Customer create(Bank b) {
		Customer newc = new Customer("noname");
		b.addCustomer(newc);
		entityManager.persist(newc);
		return newc;
	}

	public Customer first() {
		List<Customer> bks = getList();
		return bks.get(0);
	}
	
	public Customer first(Bank b) {
		List<Customer> bks = getList(b);
		if (bks!=null && bks.size()>0)
		    return bks.get(0);
		else
			return null;
	}
	
	
	private Random rand = new Random();

	public Customer makeRandom() {
		Customer c = new Customer();
		c.setName("Client " + RandomString.generateStringAlpha(10));
		c.setForName("Toto" );
		c.setAddress(rand.nextInt(100) + " rue "
				+ RandomString.generateStringAlpha(10));
		c.setZipCode(Integer.toString(30000 + rand.nextInt(1000)));
		return c;
	}
	
	public Customer createRandom() {
		Customer c = makeRandom();
		entityManager.persist(c);
		return c;
	}
	
	public Customer createRandom(Bank b) {
		Customer c = makeRandom();
		b.addCustomer(c);
		entityManager.persist(c);
		return c;
	}

	public Customer delete(Customer c) {
		c = find(c.getId()); //on ne peut pas supprimer une entitï¿½ dï¿½tachï¿½e
		Customer pr = prior(c);
		if (pr==null)
			pr=next(c);
		if (c.getBank()!=null)
	       c.getBank().removeCustomer(c);
		entityManager.remove(c);
		return pr;
	}
	
	public Customer delete(Bank b, Customer c) {
		b = entityManager.find(Bank.class, b.getId());
		c = find(c.getId()); //on ne peut pas supprimer une entitï¿½ dï¿½tachï¿½e
		Customer pr = prior(b, c);
		if (pr==null)
			pr=next(b, c);
		
		c = find(c.getId());
		b.removeCustomer(c);
		entityManager.remove(c);
		return pr;
	}	

	public Customer find(int id) {
		return entityManager.find(Customer.class, id);
	}
	
	
	public Customer find(Bank b, int id) {
		return entityManager.find(Customer.class, id);
	}
	
	public Customer next(Customer c) {	
		return Paging.next(getList(),c);
	}

	public Customer prior(Customer c) {
		return Paging.prior(getList(),c);
	}

	public Customer next(Bank b, Customer c) {
		return Paging.next(getList(b),c);
	}

	public Customer prior(Bank b, Customer c) {
		return Paging.prior(getList(b),c);
	}	
	
	@SuppressWarnings("unchecked")
	public List<Customer> getList() {
		return entityManager.createNamedQuery("allcustomers").getResultList();
	}

	@SuppressWarnings("unchecked")
	public List<Customer> getList(Bank b) {
		return entityManager.createNamedQuery("allcustomersbybank").setParameter("bank", b).getResultList();
	}


	public Customer foobar(Customer c) {
		return c;
	}
	
	public Customer foobar(Bank b, Customer c) {
		return c;
	}	

	public Customer merge(Customer c) {
		if (find(c) != null) {
			entityManager.merge(c);
			return c;
		} else
			return null;
	}
	
	public Customer merge(Bank b, Customer c) {
		if (!c.getBank().equals(b))
			throw new RuntimeException("not the right bank!");
		return merge(c);
	}	

	public Customer last(Bank b) {
		List<Customer> csts = getList(b);
		return csts.get(csts.size() - 1);
	}
	
	public Customer last() {
		List<Customer> csts = getList();
		return csts.get(csts.size() - 1);
	}

	
	public List<Customer> populate(Bank b) {
		
		Customer c = create(b);
		c.setName("Internet Customer");
		c.setForName("Toto");
		c.setAddress("10, avenue de la Californie");
		c.setZipCode("13000");
		
		entityManager.merge(c);
		
	
		System.out.println(c);
		
		c = create(b);
		c.setName("Foobar Customer");
		c.setForName("Titi");
		c.setAddress("11, avenue du Nevada");
		c.setZipCode("14000");
		entityManager.merge(c);
		
		entityManager.merge(b);
		
		System.out.println(c);
		System.out.println("populating customers - end ");
		return b.getCustomers();
	}

	public Boolean isSame(Customer a, Customer b) {
		return a!=null && b!=null && a.getId() == b.getId();
	}


}
